package com.winterwar.web;

import java.net.InetSocketAddress;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Random;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.spy.memcached.MemcachedClient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.actions.DispatchAction;

import com.winterwar.base.Convention;
import com.winterwar.base.Event;
import com.winterwar.base.RegisteredEvent;
import com.winterwar.base.Registration;
import com.winterwar.base.User;
import com.winterwar.base.WWAuthenticator;
import com.winterwar.service.ConventionManager;
import com.winterwar.service.EventManager;
import com.winterwar.service.RegisteredEventManager;
import com.winterwar.service.RegistrationManager;
import com.winterwar.service.UserManager;

public class UserAction extends DispatchAction{
	private static Log log = LogFactory.getLog(UserAction.class);
	private UserManager mgr;
	private RegisteredEventManager regEventMgr;
	private EventManager eventMgr;
	private RegistrationManager regMgr;
	private ConventionManager conMgr;
	
	public void setConventionManager(ConventionManager mgr){
		this.conMgr = mgr;
	}
	public void setManager(UserManager mgr){
		this.mgr = mgr;
	}
	
	public void setRegisteredEventManager(RegisteredEventManager mgr){
		this.regEventMgr = mgr;
	}
	public void setEventManager(EventManager mgr){
		this.eventMgr = mgr;
	}
	public void setRegistrationManager(RegistrationManager mgr){
		this.regMgr = mgr;
	}
	
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	throws Exception {
		if(log.isDebugEnabled()){
			log.debug("Starting delete...");
		}
		User user = mgr.get(request.getParameter("user.userID"));
		for(Registration reg: user.getRegistrations()){
			for(int i=0;i<reg.getEvents().size();i++){
				RegisteredEvent regEvent = (RegisteredEvent)reg.getEvents().toArray()[i];
				regEventMgr.remove(regEvent.getRegEventID().toString());
			}
			regMgr.remove(reg.getRegID().toString());
		}
		for(Event e: user.getSubmittedEvents()){
			e.setUserID(0);
			eventMgr.save(e);
		}
		user = null;
		mgr.remove(request.getParameter("user.userID"));
		ActionMessages messages = new ActionMessages();
		messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.deleted"));
		saveMessages(request, messages);
		return list(mapping, form, request, response);
	}

	public ActionForward save(ActionMapping mapping, ActionForm form,
				HttpServletRequest request, HttpServletResponse response)
	throws Exception {
		if(log.isDebugEnabled()){
			log.debug("Starting save...");
		}
		ActionMessages errors = form.validate(mapping, request);
		if(!errors.isEmpty()){
			saveErrors(request, errors);
			return mapping.findForward("edit");
		}
		Random gen = new Random(new Date().getTime());
		HttpSession session = request.getSession();
		DynaActionForm userForm = (DynaActionForm) form;
		ActionMessages messages = new ActionMessages();
		User test = (User)  userForm.get("user");
		if(test.getUserID() == null || test.getUserID().intValue() == 0){
			test = mgr.getByUserName(test.getUsername());
			if(test != null && test.getEmail().compareTo("none@noemail.net") != 0){
				errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.exists"));
				saveErrors(request, errors);
				return mapping.findForward("edit");
			} else {
				test = (User)  userForm.get("user");
				test = mgr.getByFirstAndLast(test.getFirstName(), test.getLastName());
				if(test != null){
					errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.exists"));
					saveErrors(request, errors);
					return mapping.findForward("edit");
				}
			}
		}
		if(session.getAttribute("randFormID").toString().equals(request.getParameter("formID").toString())){
			resetToken(request);
			User user = (User) userForm.get("user");
			if(user.getCreated() == null)
				user.setCreated(new Date());
			if(user.getInactive() == null)
				user.setInactive(new Boolean(false));
			user = mgr.save(user);
			session.setAttribute("userID", user.getUserID());
			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.saved"));
			saveMessages(request, messages);
			session.setAttribute("randFormID", gen.nextInt() + "");
		}
		else {
			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.repost"));
			saveMessages(request, messages);
		}
		if(request.getParameter("where") != null && request.getParameter("where").toString().equals("admin"))
			return list(mapping, form, request, response);
		else 
			return mapping.findForward("saved");
	}

	public ActionForward edit(ActionMapping mapping, ActionForm form,
					HttpServletRequest request, HttpServletResponse response)
	throws Exception {
		if(log.isDebugEnabled()){
			log.debug("Starting edit...");
		}
		DynaActionForm userForm = (DynaActionForm) form;
		String userID = request.getParameter("userID");
		MemcachedClient cacheClient = new MemcachedClient(new InetSocketAddress("localhost", 11211));
		String conID = (cacheClient.get("Curr_Con_ID") != null) ? cacheClient.get("Curr_Con_ID").toString() : null;;
		if(conID == null || conID.equals("")){
			conID = conMgr.getCurrentCon().getConID().toString();
			cacheClient.set("Curr_Con_ID", 86400, conID);
		}
		
		request.setAttribute("conID", conID);
		if(userID != null){
			User user = mgr.get(userID);
			if(user == null){
				ActionMessages errors = new ActionMessages();
				errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.missing"));
				saveErrors(request, errors);
				
				return mapping.findForward("list");
			}
			request.setAttribute("user", user);
			userForm.set("user", user);
		}
		return mapping.findForward("edit");
	}
	
	public ActionForward list(ActionMapping mapping, ActionForm form,
						HttpServletRequest request, HttpServletResponse response)
	throws Exception {
		if(log.isDebugEnabled()){
			log.debug("Starting list...");
		}
		request.setAttribute("users", mgr.getAll());
		
		return mapping.findForward("list");
	}

	public ActionForward login(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	throws Exception {
		if(log.isDebugEnabled()){
			log.debug("Starting delete...");
		}
		HttpSession session = request.getSession();
		User user = mgr.login(request.getParameter("user.username"), request.getParameter("user.password"));
		if(user != null && !user.getInactive()){
			session.setAttribute("userID", user.getUserID());
			session.setAttribute("userLevel", user.getLevel());
			session.setAttribute("userFirstName", user.getFirstName());
			ActionMessages messages = new ActionMessages();
			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.login"));
			saveMessages(request, messages);
			return mapping.findForward("loginSuccess");
		} else if(user != null && user.getInactive()){
			ActionMessages messages = new ActionMessages();
			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.inactiveError"));
			saveMessages(request, messages);
			return mapping.findForward("loginFail");
		} else {
			session.removeAttribute("userID");
			ActionMessages messages = new ActionMessages();
			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.loginFailed"));
			saveMessages(request, messages);
			return mapping.findForward("loginFail");
		}
	}
	public ActionForward logout(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	throws Exception {
		if(log.isDebugEnabled()){
			log.debug("Starting delete...");
		}
		HttpSession session = request.getSession();
		session.removeAttribute("userID");
		session.removeAttribute("userLevel");
		ActionMessages messages = new ActionMessages();
		messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("user.loggedout"));
		saveMessages(request, messages);
		return mapping.findForward("logout");
	}
	
	public ActionForward forgotInfo(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	throws Exception{
		if(log.isDebugEnabled()){
			log.info("Starting send mail...");
		}
		ActionMessages messages = new ActionMessages();
		String eMail = request.getParameter("eMail");
		List users;
		StringBuilder eMailBody = new StringBuilder();
		try{
		eMailBody.append("Hello from the offices of the Winter War Convention's Registrar!\n\r\n\r");
		eMailBody.append("You are receiving this information due to a request from our website for your account login information to be sent to this eMail address. If you did not make the request, please disregard this notification.  No personal or account information has been sent to any parties other than the owner of this eMail address.\n\r\n\r");
		eMailBody.append("Your login information is: \n\r");

		if(eMail != null){
			users = mgr.getByEmail(eMail);
			if(users.size() > 0){
				String[] to = {eMail};
				for(int i=0;i<users.size();i++){
					User user = (User) users.get(i);
					eMailBody.append("For User : " + user.getFirstName() + " " + user.getLastName() + "\n\r");
					eMailBody.append("     User Name : " + user.getUsername() + "\n\r");
					eMailBody.append("    Password : " + user.getPassword() + "\n\r\n\r");
					
				}

				Properties props = new Properties();
				props.put("mail.smtp.host", "winterwar.org");
			    props.put("mail.smtp.auth", "true");
			    props.put("mail.smtp.user", "registrar@mail.winterwar.org");
			    props.put("mail.smtp.pass", "Battle0n"); 	
				//Get the default Session
				Session mailSession = Session.getDefaultInstance(props, new WWAuthenticator());
				
				// create a message
				Message msg = new MimeMessage(mailSession);
				
				// set the from and to address
				InternetAddress addressFrom = new InternetAddress("registrar@winterwar.org");
				msg.setFrom(addressFrom);
				InternetAddress[] addressTo = new InternetAddress[to.length]; 
							
				
				for (int i = 0; i < to.length; i++)
				{
				    addressTo[i] = new InternetAddress(to[i]);
				}
				msg.setRecipients(Message.RecipientType.TO, addressTo);
				
				
				//You can also set your custom headers in the Email if you Want
				msg.addHeader("MyHeaderName", "myHeaderValue");
				
				// Setting the Subject and Content Type
				msg.setSubject("Winter War Convention Account Information");
				msg.setContent(eMailBody.toString(), "text/plain");
				Transport.send(msg);
				
				request.setAttribute("message", "Thank you! Your login information will be emailed to the supplied address soon! If you do not receive this e-mail, please contact <a href=\"smckin@gmail.com\">Susan McKinney</a>.");
			} else {
				request.setAttribute("message", "We're sorry, but we do not recongnize that address. Please contact <a href=\"smckin@gmail.com\">Susan McKinney</a>.");
			}
		}
		} catch(Exception ex){
			log.error(ex);
			request.setAttribute("message", "We're sorry, but there seems to be some error. Please contact <a href=\"smckin@gmail.com\">Susan McKinney</a>.");
		}
		return mapping.findForward("forgotPassword");
	}
}
